home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / perlref-.001 / perlref-~ / perlref-5.001.2 / parr.pl < prev    next >
Encoding:
Perl Script  |  1996-01-13  |  8.0 KB  |  316 lines

  1. #!/usr/local/bin/perl
  2. $RCS_Id = '$Id: parr.pl,v 5.11 1995/12/28 22:34:12 jv Exp $ ';
  3.  
  4. # Author          : Johan Vromans
  5. # Created On      : Aug 15 1991
  6. # Based On        : parr.pl by jgreely@cis.ohio-state.edu, 89/10/23
  7. # Last Modified By: Johan Vromans
  8. # Last Modified On: Thu Dec 28 23:32:55 1995
  9. # Update Count    : 94
  10. # Status          : OK
  11.  
  12. ################ Common stuff ################
  13.  
  14. $my_package = "PerlRef";
  15. ($my_name, $my_version) = $RCS_Id =~ /: (.+).pl,v ([\d.]+)/;
  16. $my_version .= '*' if length('$Locker:  $ ') > 12;
  17.  
  18. ################ Program parameters ################
  19.  
  20. &options;
  21.  
  22. ################ Presets ################
  23.  
  24. $verbose = $opt_verbose;
  25. $debug = $opt_debug;
  26. $trace = $opt_test || $opt_trace | $opt_debug;
  27. $TMPDIR = $ENV{"TMPDIR"} || "/usr/tmp";
  28. $TMPDIR = "/tmp" unless -d $TMPDIR;
  29.  
  30. ################ The Process ################
  31.  
  32. # Read the input file, and split into parts.
  33. # We gather some info in the fly.
  34. $file = "$TMPDIR/p$$.header";
  35. @files = ($file);
  36. $sheet = 0;
  37.  
  38. open (FILE, ">$file") || die ("$file: $!\n");
  39.  
  40. while ( <> ) {
  41.     # Hack to use NeXT Preview: strip old '%%Pages:' lines.
  42.     if ( /^%%Pages:/ ) {
  43.     $npages = $1 if $' =~ /\s*(\d+)/;
  44.     print STDERR ("Number of pages = $npages.\n") if $verbose;
  45.     next;
  46.     }
  47.     if ( /^%%Page:/ ) {
  48.     $sheet++;
  49.     $pagemap{$sheet} = $1 if /%%Page:\s+(\S+)\s+\S+/;
  50.     close (FILE);
  51.     $file = "$TMPDIR/p$$.$sheet";
  52.     push (@files, $file);
  53.     open (FILE, ">$file") || die ("$file: $!\n");
  54.     }
  55.     if ( /^%%Trailer/ ) {
  56.     close (FILE);
  57.     $file = "$TMPDIR/p$$.trailer";
  58.     push (@files, $file);
  59.     open(FILE, ">$file") || die ("$file: $!\n");
  60.     }
  61.     if ( /^%%EndSetup/ ) {
  62.     # Insert twoup before switching to TeXDict.
  63.     &twoup;
  64.     $twoup++;
  65.     &double_sided if $opt_duplex;
  66.     print FILE ("%%EndSetup\n");
  67.     next;
  68.     }
  69.     if ( $opt_letter ) {
  70.     # Special treatment for US letter freaks.
  71.     if ( /^%%BoundingBox:\s*0 0 596 842/ ) {
  72.         $_ = "%%BoundingBox: 0 0 612 792\n";
  73.     }
  74.     if ( /^%%DocumentPaperSizes: A4/i ) {
  75.         $_ = "%%DocumentPaperSize: Letter\n";
  76.     }
  77.     if ( /^%%BeginPaperSize: A4/i ) {
  78.         scalar (<>);
  79.         $_ = "%%BeginPaperSize: Letter\nletter\n";
  80.     }
  81.     if ( /^%%PaperSize: A4/i ) {
  82.         $_ = "%%PaperSize: Letter\n";
  83.     }
  84.     }
  85.     print FILE ($_);
  86. }
  87. close (FILE);
  88. die ("twoup insertion error\n") unless $twoup == 1;
  89.  
  90. # Calculate order to output the pages.
  91. @order = ();
  92. if ( $opt_order ne '' ) {
  93.     # Explicit range given.
  94.     foreach $range ( split (/,/, $opt_order) ) {
  95.     ($start,$sep,$end) = split (/(-)/, $range);
  96.     $start = 1 unless $start;
  97.     $end = $sheet unless $end;
  98.     if ($sep) {
  99.         push (@order, $start..$end);
  100.     }
  101.     else{
  102.         push (@order, $start);
  103.     }
  104.     }
  105. }
  106. elsif ( $opt_bookorder ) {
  107.     # Normal book order: 8,1,2,7,6,3,4,5.
  108.     # warn ("Warning: number of pages ($npages) is not a multiple of 4\n")
  109.     #    unless $npages % 4 == 0;
  110.     @order = &bookorder (4*int($npages/4), $npages%4);
  111.     if ( $opt_odd ) {
  112.     # Select odd pages: 8,1,6,3.
  113.     @tmp = @order;
  114.     @order = ();
  115.     while ( @tmp > 0 ) {
  116.         push (@order, shift (@tmp), shift (@tmp));
  117.         shift (@tmp); shift (@tmp);
  118.     }
  119.     }
  120.     elsif ( $opt_even ) {
  121.     @tmp = @order;
  122.     @order = ();
  123.     if ( $opt_reverse ) {
  124.         # Even pages: 2,7,4,5.
  125.         while ( @tmp > 0 ) {
  126.         shift (@tmp); shift (@tmp);
  127.         push (@order, shift (@tmp), shift (@tmp));
  128.         }
  129.     }
  130.     else {
  131.         # Even pages: 4,5,2,7.
  132.         while ( @tmp > 0 ) {
  133.         shift (@tmp); shift (@tmp);
  134.         unshift (@order, shift (@tmp), shift (@tmp));
  135.         }
  136.     }
  137.     }
  138. }
  139. else {
  140.     # Pages in order. Make sure it's even.
  141.     @order = (1..$sheet);
  142.     push (@order, $sheet+1) if $sheet % 2;
  143. }
  144.  
  145. # Mark pages out of order.
  146. grep ((($_ > $sheet) && ($_ = '*')) || 1, @order);
  147. print STDERR ("Page order = ", join(',',@order), "\n") if $verbose;
  148.  
  149. # Now glue the parts in the correct order together.
  150. # The preamble info.
  151. open (FILE, "$TMPDIR/p$$.header");
  152. $_ = <FILE>;
  153. print STDOUT ($_, "%%Pages: ", int((@order+1)/2), " 0\n");
  154. print STDOUT ($_) while <FILE>;
  155. close (FILE);
  156.  
  157. # The pages.
  158. $count = 0;
  159. foreach $page (@order) {
  160.     $count++;
  161.     $num = '*';
  162.     $num = $pagemap{$page} if defined $pagemap{$page};
  163.     if ( defined $order[$count] && defined $pagemap{$order[$count]} ) {
  164.     $num .= '/' . $pagemap{$order[$count]};
  165.     }
  166.     else {
  167.     $num .= '/*';
  168.     }
  169.     print STDOUT ("%%Page: $num ", ($count+1)/2, "\n") if $count & 1;
  170.     print STDOUT ("%%OldPage: $page\n");
  171.     if ($page eq "*") {
  172.     print STDOUT ("0 0 bop eop\n");
  173.     }
  174.     else {
  175.     open (FILE, "$TMPDIR/p$$.$page");
  176.     while ( <FILE> ) {
  177.         print STDOUT ($_) unless /^%%Page:/;
  178.     }
  179.     close (FILE);
  180.     }
  181. }
  182.  
  183. # The trailer info.
  184. open (FILE, "$TMPDIR/p$$.trailer");
  185. print STDOUT ($_) while <FILE>;
  186. close (FILE);
  187.  
  188. # Wrapup and exit.
  189. unlink @files unless $opt_debug || $opt_test;
  190. exit(0);
  191.  
  192. ################ Subroutines ################
  193.  
  194. sub bookorder {
  195.     local ($pages, $offset) = @_;
  196.     local (@order) = ();
  197.     for ($i=1; $i<$pages/2; $i+=2) {
  198.     push (@order, $pages-$i+1+$offset, $i+$offset, 
  199.           $i+1+$offset, $pages-$i+$offset);
  200.     }
  201.     @order;
  202. }
  203.  
  204. sub twoup {
  205.     local ($factor) = 0.707106781187;    # ridiculous (0.7 would do as well)
  206.     local ($scale) = 72/75;
  207.     $opt_shift *= $scale;
  208.     $opt_topshift *= $scale;
  209.  
  210.     # Measurements are in 1/100 inch approx.
  211.     # topmargin value shifts UP.
  212.     # leftmargin value shifts RIGHT.
  213.     if ( $opt_a4) {
  214.     $topmargin = -5 - $opt_topshift;
  215.     $leftmargin = 112 + $opt_shift;
  216.     $othermargin = -445;    # do not change -- relative to $leftmargin
  217.     $leftmargin -= $othermargin;
  218.     }
  219.     else {
  220.     $topmargin = 10 - $opt_topshift;
  221.     $leftmargin = 77 + $opt_shift;
  222.     $othermargin = -445;    # do not change -- relative to $leftmargin
  223.     $leftmargin -= $othermargin;
  224.     }
  225.     print FILE <<EOD;
  226. /isls true def
  227. userdict begin 
  228. /isoddpage true def
  229. /orig-showpage /showpage load def
  230. /showpage {
  231.         isoddpage not { orig-showpage } if
  232.         /isoddpage isoddpage not store 
  233.     } def
  234.  
  235. /bop-hook {
  236.         isoddpage 
  237.     { $factor $factor scale $topmargin $leftmargin translate }
  238.         { 0 $othermargin translate}
  239.     ifelse
  240.     } def
  241.  
  242. /end-hook{ isoddpage not { orig-showpage } if } def
  243. end
  244. EOD
  245. }
  246.  
  247. sub double_sided {
  248.  
  249.     # From: Tim Huckvale <tjh@praxis.co.uk>
  250.     #
  251.     # You may be interested in the following problem, and fix, that we
  252.     # found when attempting to print the reference card on our Hewlett
  253.     # Packard Laser-Jet IIISi printer.
  254.     # 
  255.     # On this printer, refguide.ps prints double-sided with the
  256.     # reverse side of each sheet upside down.  We fixed it with the
  257.     # following patch, applied before printing.
  258.  
  259.     # From: Johan Vromans <jvromans@squirrel.nl>
  260.     #
  261.     # Okay -- consider this an unsupported feature.
  262.  
  263.     print FILE <<EOD;
  264. statusdict /setduplexmode known { statusdict begin true setduplexmode end } if
  265. statusdict /settumble known { statusdict begin true settumble end } if
  266. EOD
  267. }
  268.  
  269. sub options {
  270.     local ($opt_help) = 0;    # handled locally
  271.     local ($opt_ident) = 0;    # handled locally
  272.  
  273.     # Preset defaults.
  274.     $opt_trace = $opt_debug = 0;
  275.     $opt_verbose = 0;
  276.     $opt_bookorder = $opt_even = $opt_odd = $opt_reverse = 0;
  277.     $opt_a4 = $opt_letter = 0;
  278.     $opt_order = '';
  279.     $opt_shift = $opt_topshift = 0;
  280.  
  281.     # Process options.
  282.     if ( @ARGV > 0 && $ARGV[0] =~ /^[-+]/ ) {
  283.     require "newgetopt.pl";
  284.     &usage 
  285.         unless &NGetOpt ("ident", "verbose",
  286.                  "bookorder", "order=s", "a4", "letter",
  287.                  "odd", "even", "reverse", "duplex",
  288.                  "shift=i", "topshift=i",
  289.                  "trace", "help", "debug")
  290.         && !$opt_help;
  291.     }
  292.     print STDERR "This is $my_package [$my_name $my_version]\n"
  293.     if $opt_ident;
  294. }
  295.  
  296. sub usage {
  297.     print STDERR <<EndOfUsage;
  298. This is $my_package [$my_name $my_version]
  299. Usage: $0 [options] [file ...]
  300.     -a4        map for A4 size paper
  301.     -letter    map for US Letter size paper
  302.     -bookorder    output pages in book order
  303.     -odd    odd pages only (use with -bookorder)
  304.     -even    even pages only (use with -bookorder)
  305.     -shift NN    shift right by NN units (1/100 inch approx.)
  306.     -topshift NN    shift down by NN units (1/100 inch approx.)
  307.     -reverse    reversed order (use with -bookorder -even)
  308.     -duplex    try duplex printing
  309.     -order n,n,...    explicit page order
  310.     -help    this message
  311.     -ident    show identification
  312.     -verbose    verbose information
  313. EndOfUsage
  314.     exit 1;
  315. }
  316.